package org.dromara.web.controller.app;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.UserConstants;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.utils.IpUtils;
import org.dromara.common.core.utils.MessageUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.ValidatorUtils;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.web.core.BaseController;
import org.dromara.dao.business.domain.User;
import org.dromara.dao.business.enums.SettingKeys;
import org.dromara.dao.system.domain.vo.SysClientVo;
import org.dromara.web.controller.app.req.LoginReq;
import org.dromara.web.controller.app.req.UpdateAvatarReq;
import org.dromara.web.controller.app.req.UpdateNameReq;
import org.dromara.web.controller.business.req.UserReq;
import org.dromara.web.domain.app.UserShareVO;
import org.dromara.web.domain.vo.LoginVo;
import org.dromara.web.service.auth.IAuthStrategy;
import org.dromara.web.service.business.SettingsService;
import org.dromara.web.service.business.UserService;
import org.dromara.web.service.system.ISysClientService;
import org.dromara.web.utils.UserTypeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Map;


/**
 * 用户相关
 *
 * @date 2024-09-14 08:20:08
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/app/user")
public class AppUserController extends BaseController {

    @Autowired
    private UserService userService;
    @Autowired
    private ISysClientService clientService;
    @Autowired
    private SettingsService settingsService;

    @Value("${user.share-link}")
    String shareLink;

    /**
     * 用户账号登录
     *
     * @param body
     * @return
     */
    @Operation(requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(content = @Content(schema = @Schema(implementation = LoginReq.class))))
    @SaIgnore
    @PostMapping("/login")
    public R<LoginVo> login(@RequestBody LoginReq body, @RequestHeader("clientid") String clientId) {
        ValidatorUtils.validate(body);
        // 授权类型和客户端id
        if (ObjectUtil.isNotEmpty(body.getClientId())) {
            clientId = body.getClientId();
        }
        String grantType = "password";
        SysClientVo client = clientService.queryByClientId(clientId);
        // 查询不到 client 或 client 内不包含 grantType
        if (ObjectUtil.isNull(client) || !StringUtils.contains(client.getGrantType(), grantType)) {
            log.info("客户端id: {} 认证类型：{} 异常!.", clientId, grantType);
            return R.fail(MessageUtils.message("auth.grant.type.error"));
        } else if (!UserConstants.NORMAL.equals(client.getStatus())) {
            return R.fail(MessageUtils.message("auth.grant.type.blocked"));
        }
        JSONObject jsonObject = JSONObject.parseObject(JsonUtils.toJsonString(body));
        jsonObject.put("grantType", grantType);



        // 登录
        LoginVo loginVo = IAuthStrategy.login(JsonUtils.toJsonString(jsonObject), client, grantType);
//        LoginVo loginVo = null;
//        if (client.getDeviceType().equals("app")) {
//            loginVo = IAuthStrategy.login(JsonUtils.toJsonString(jsonObject), client, grantType);
//        } else {
//            loginVo = userService.pcLogin(body.getUsername(), body.getPassword(), clientId);
//        }
        return R.ok(loginVo);
    }


    /**
     * 用户注册
     *
     * @param req
     * @param request
     * @return
     */
    @Operation
    @SaIgnore
    @PostMapping("/register")
    public R<Void> register(@RequestBody @Validated UserReq.RegisterReq req, HttpServletRequest request) {
        String ip = IpUtils.getIpAddr(request);
        userService.frontRegister(req, ip);
        return R.ok();
    }


    /**
     * 用户注册
     *
     * @param req
     * @param request
     * @return
     */
    @Operation
    @SaIgnore
    @PostMapping("/deviceRegister")
    public R<LoginVo> registerDevice(@RequestBody @Validated UserReq.DeviceRegisterReq req, HttpServletRequest request, @RequestHeader("clientid") String clientId) {
        String ip = IpUtils.getIpAddr(request);
        LoginVo loginVo = userService.deviceRegisterLogin(req.getDeviceId(), ip, clientId);
        return R.ok(loginVo);
    }


    @PostMapping("/refreshPassword")
    public R<User> refreshPassword() {
        return R.ok(userService.refreshPassword(LoginHelper.getAppUserId()));
    }


    /**
     * 当前用户信息
     *
     * @return
     */
    @Operation
    @RequestMapping(value = "/login_user", method = {RequestMethod.POST, RequestMethod.GET})
    public R<User> loginUser() {
        Long userId = LoginHelper.getAppUserId();
        if (userId == null) {
            return R.ok();
        }

        User user = userService.queryById(userId);
        user.setUserType(UserTypeUtils.userType(user));
        return R.ok(user);
    }


    /**
     * 更新用户昵称
     *
     * @return
     */
    @Operation
    @PostMapping("/updateName")
    public R<String> updateName(@RequestBody @Validated UpdateNameReq req) {
        LoginUser loginUser = LoginHelper.getAppLoginUser();
        userService.updateUserName(loginUser.getUserId(), req.getName());
        return R.ok();
    }


    /**
     * 更新用户头像
     *
     * @param req
     * @return
     */
    @Operation
    @PostMapping("/updateAvatar")
    public R<Void> updateAvatar(@RequestBody @Validated UpdateAvatarReq req) {
        LoginUser loginUser = LoginHelper.getAppLoginUser();
        userService.updateAvatar(loginUser.getUserId(), req.getAvatar());
        return R.ok();
    }

    /**
     * 用户分享链接
     *
     * @return
     */
    @Operation
    @GetMapping("/share")
    public R<UserShareVO> shareLink() {
        LoginUser loginUser = LoginHelper.getAppLoginUser();
        User user = userService.queryById(loginUser.getUserId());
        UserShareVO shareVO = new UserShareVO();
        shareVO.setUrl(String.format(shareLink, user.getInviteCode()));
        Map<String, String> settingMap = settingsService.getSettingsMap();
        try {
            shareVO.setFirstDiamondCount(Integer.parseInt(settingMap.get(SettingKeys.INVITE_DIAMOND_COUNT)));
            shareVO.setFirstStarCount(Integer.parseInt(settingMap.get(SettingKeys.INVITE_DIAMOND_COUNT)));
            shareVO.setMoreDiamondCount(Integer.parseInt(settingMap.get(SettingKeys.INVITE_MORE_DIAMOND_COUNT)));
            shareVO.setMoreStarCount(Integer.parseInt(settingMap.get(SettingKeys.INVITE_MORE_STAR_COUNT)));
            shareVO.setRegisterDiamondCount(Integer.parseInt(settingMap.get(SettingKeys.INVITE_REGISTER_DIAMOND_COUNT)));
        } catch (Exception e) {

        }
        return R.ok(shareVO);
    }

}
